﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.Composition.Hosting;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.ComponentModel.Composition.Primitives;

namespace WebRole1
{
    /// <summary>
    /// Simple encapsulation example of DirectoryCatalog.  
    /// </summary>
    public class AzureStorageCatalog:ComposablePartCatalog
    {
        private string _localCatalogDirectory = default(string);
        private DirectoryCatalog _directoryCatalog = default(DirectoryCatalog);

        AzureStorageCatalog(string StorageSetting, string ContainerName)
            :base()
        {
            //pull the files to the local directory
            _localCatalogDirectory = GetStorageCatalog(StorageSetting, ContainerName);
            //load the exports using an encapsulated DirectoryCatalog
            _directoryCatalog = new DirectoryCatalog(_localCatalogDirectory);
            
        }

        //return encapsulated parts
        public override IQueryable<ComposablePartDefinition> Parts
        {
            get { return _directoryCatalog.Parts; }
        }

        private string GetStorageCatalog(string StorageSetting, string ContainerName)
        {
            string containerName = ContainerName;

            // using development storage account
            CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting(StorageSetting);

            // create the blob client and use it to create the container object
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // note that here is where the container name is passed in order to get to the files we want
            CloudBlobContainer blobContainer = new CloudBlobContainer(storageAccount.BlobEndpoint.ToString() + "/" + containerName, blobClient);

            // create the options needed to get the blob list
            BlobRequestOptions options = new BlobRequestOptions();
            options.AccessCondition = AccessCondition.None;
            options.BlobListingDetails = BlobListingDetails.All;
            options.UseFlatBlobListing = true;
            options.Timeout = new TimeSpan(0, 1, 0);

            // retrieve the list of files/blobs in the container.  There are ways to fetch by prefix, but in this instance we want them all
            System.Collections.Generic.IEnumerable<IListBlobItem> blobs = blobContainer.ListBlobs(options);

            List<Type> typesToLoad = new List<Type>();

            // iterate over the collect. grab the files and save them locally.
            foreach (IListBlobItem item in blobs)
            {
                // raw path: \Resources%2fdevstoreaccount1%2fresources%2fbusinesscommon.dll'
                string fileAbsPath = item.Uri.AbsolutePath.ToLower();
                // just want the file name...
                fileAbsPath = fileAbsPath.Substring(fileAbsPath.LastIndexOf('/') + 1);

                try
                {
                    Microsoft.WindowsAzure.StorageClient.CloudPageBlob pageblob = new CloudPageBlob(item.Uri.ToString());
                    pageblob.DownloadToFile(MEFContext.CacheFolderPath + fileAbsPath, options);

                    
                }
                catch (Exception)
                {
                    // Ignore exceptions, if we can't write it's because we've already got the file, move on
                }
            }
           

            return MEFContext.CacheFolderPath;
        }

    }
}